package com.yumo.kangchenjunga.activity;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.yumo.kangchenjunga.coupon.v1.ImportFailedException;
import com.yumo.kangchenjunga.coupon.v1.ImportResult;
import com.yumo.kangchenjunga.exception.controller.HttpBadRequestException;
import com.yumo.kangchenjunga.exception.controller.HttpNotFoundException;

@RestController
@RequestMapping("/api/v1/activities")
public final class ActivityController {

	@Autowired
	private ActivityService service;

	@GetMapping("/{id}")
	public Activity queryById(@PathVariable int id) throws HttpNotFoundException {
		try {
			return service.queryById(id);
		} catch (NoSuchActivityException e) {
			throw HttpNotFoundException.build(e, "权益 [ id: %d ] 不存在。", id);
		}
	}

	@GetMapping("/")
	public List<Activity> list(@RequestParam Optional<Integer> companyId) {
		return companyId.map(service::listByCompanyId).orElseGet(service::list);
	}

	@GetMapping(path = "/", params = { "paged" })
	public Page<Activity> page(
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		return service.page(pageable);
	}

	@PostMapping("/service/query")
	public Page<Activity> query(@RequestBody Activity activity,
			@PageableDefault(page = 0, size = 10, sort = "id", direction = Direction.DESC) Pageable pageable) {
		return service.query(activity, pageable);
	}

	@PostMapping("/")
	public Activity newActivity(@RequestBody Activity activity) {
		return service.newActivity(activity);
	}

	@DeleteMapping("/{id}")
	public void deleteActivity(@PathVariable int id) throws HttpBadRequestException {
		try {
			service.deleteActivity(id);
		} catch (ActivityAlreadyIssuedCouponException e) {
			throw HttpBadRequestException.build(e, "权益 [ id: %d ] 已经发放过优惠券。", id);
		}
	}

	@PostMapping("/{id}/interrupt")
	public void interrupt(@PathVariable int id, @RequestParam(defaultValue = "true") boolean ignoreCoupons) {
		service.interrupt(id, ignoreCoupons);
	}

	@PutMapping("/{id}")
	public Activity modifyActivity(@PathVariable int id, @RequestBody Activity activity)
			throws HttpNotFoundException, HttpBadRequestException {
		if (id == activity.getId()) {
			try {
				return service.modifyActivity(id, activity);
			} catch (NoSuchActivityException e) {
				throw HttpNotFoundException.build(e, "权益 [ id: %d ] 不存在。", id);
			} catch (ActivityAlreadyIssuedCouponException e) {
				throw HttpBadRequestException.build(e, "权益 [ id: %d ] 已经发放过优惠券。", id);
			}
		}

		throw HttpBadRequestException.build("The id in the path(%d) and body(%d) does not match.", id,
				activity.getId());
	}

	@GetMapping("/{activityId}/stores")
	public List<Integer> getActivityStore(@PathVariable int activityId) {
		return service.listActivityStore(activityId);
	}

	@PutMapping("/{activityId}/stores")
	public void modifyActivityStore(@PathVariable int activityId, @RequestBody List<Integer> storeIds)
			throws HttpNotFoundException {
		try {
			service.modifyActivityStore(activityId, storeIds);
		} catch (NoSuchActivityException e) {
			throw HttpNotFoundException.build(e, "权益 [ id: %d ] 不存在。", activityId);
		}
	}

	@PutMapping("/{activityId}/coupons/import")
	public ImportResult importCoupon(@RequestParam("file") MultipartFile file, @PathVariable int activityId)
			throws IOException, HttpNotFoundException, HttpBadRequestException {
		if (file.isEmpty()) {
			throw HttpBadRequestException.build("Empty file.");
		}

		try {
			return service.importCoupon(file.getInputStream(), activityId);
		} catch (NoSuchActivityException e) {
			throw HttpNotFoundException.build(e, "权益 [ id: %d ] 不存在。", activityId);
		}
	}

	@ExceptionHandler(ImportFailedException.class)
	public ResponseEntity<ImportResult> handler(ImportFailedException e) {
		return ResponseEntity.badRequest().body(e.result);
	}

}
